home *** CD-ROM | disk | FTP | other *** search
/ MacGames Sampler / PHT MacGames Bundle.iso / MacSource Folder / Samples from the CD / Editors / emacs / Emacs-1.14b1-sources / sources / mac-emacs-src / sysdep.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-30  |  5.6 KB  |  241 lines  |  [TEXT/EMAC]

  1. /*
  2.  * Portions of this file Copyright (C) 1985, 1986, 1987, 1988,
  3.  *     1990 Free Software Foundation, Inc.
  4.  * Portions of this file Copyright (C) 1993, 1994 Marc Parmet.
  5.  * This file is part of the Macintosh port of GNU Emacs.
  6.  *
  7.  * GNU Emacs is distributed in the hope that it will be useful,
  8.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.  * GNU General Public License for more details.
  11.  */
  12.  
  13. #if defined(THINK_C)
  14. #include <MacHeaders>
  15. #else
  16. #include <Types.h>
  17. #include <Memory.h>
  18. #include <Quickdraw.h>
  19. #include <Windows.h>
  20. #include <Resources.h>
  21. #endif
  22.  
  23. #include <Processes.h>
  24. #include "sys/ioctl.h"
  25. #include <setjmp.h>
  26. #include "signal.h"
  27. #include "stdio.h"
  28. #include "termhooks.h"
  29. #include "config.h"
  30. #include "lisp.h"
  31. #include "dispextern.h"
  32.  
  33. char *sys_siglist[] = {
  34.     "bum signal!!",
  35.     "aborted",
  36.     "floating point exception",
  37.     "illegal instruction",
  38.     "interrupted",
  39.     "segmentation violation",
  40.     "terminated",
  41.     "hangup",
  42.     "killed",
  43.     "alarm clock",
  44.     "quit",
  45.     "bad argument to system call",
  46.     "iot instruction",
  47.     "bus error",
  48.     "bad argument to system call",
  49.     "write on a pipe with no one to read it",
  50.     "child status has changed",
  51. };
  52.  
  53. /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
  54.  * Only checks read descriptors.
  55.  */
  56. /* How long to wait between checking fds in select */
  57. #define SELECT_PAUSE 1
  58. int select_alarmed;
  59.  
  60. select_alarm ()
  61. {
  62.   select_alarmed = 1;
  63.   signal (SIGALRM, SIG_IGN);
  64. }
  65.  
  66. /* Only rfds are checked.  */
  67. int
  68. select (nfds, rfds, wfds, efds, timeout)
  69.      int nfds;
  70.      int *rfds, *wfds, *efds, *timeout;
  71. {
  72.     int ravail = 0, orfds = 0, old_alarm;
  73.     int timeoutval = timeout ? *timeout : 100000;
  74.     int *local_timeout = &timeoutval;
  75.     extern int kbd_count;
  76.     extern int proc_buffered_char[];
  77. #ifndef subprocesses
  78.     int process_tick = 0, update_tick = 0;
  79. #else
  80.     extern int process_tick, update_tick;
  81. #endif
  82.     int (*old_trap) ();
  83.     char buf;
  84.     
  85.     if (rfds)
  86.     {
  87.         orfds = *rfds;
  88.         *rfds = 0;
  89.     }
  90.     if (wfds)
  91.         *wfds = 0;
  92.     if (efds)
  93.         *efds = 0;
  94.     
  95.     /* If we are looking only for the terminal, with no timeout,
  96.        just read it and wait -- that's more efficient.  */
  97.     if (orfds == 1 && (!timeout || *timeout == 100000)
  98.         && process_tick == update_tick)
  99.     {
  100.         if (!kbd_count)
  101.             read_input_waiting ();
  102.         *rfds = 1;
  103.         return 1;
  104.     }
  105.     
  106.     /* Once a second, till the timer expires, check all the flagged read
  107.      * descriptors to see if any input is available.  If there is some then
  108.      * set the corresponding bit in the return copy of rfds.
  109.      */ 
  110.     while (1) {
  111.         register int to_check, bit, fd;
  112.         
  113.         if (rfds) {
  114.             for (to_check = nfds, bit = 1, fd = 0; --to_check >= 0; bit <<= 1, fd++) {
  115.                 if (orfds & bit) {
  116.                     int avail = 0, status = 0;
  117.                     
  118.                     if (bit == 1)
  119.                         avail = detect_input_pending (); /* Special keyboard handler */
  120.                     else
  121.                         status = ioctl (fd, FIONREAD, &avail);
  122.                     if (status >= 0 && avail > 0) {
  123.                         (*rfds) |= bit;
  124.                         ravail++;
  125.                     }
  126.                 }
  127.             }
  128.         }
  129.         if (*local_timeout == 0 || ravail != 0 || process_tick != update_tick)
  130.             break;
  131.         old_alarm = alarm (0);
  132.         old_trap = (int (*)()) signal (SIGALRM, select_alarm);
  133.         select_alarmed = 0;
  134.         alarm (SELECT_PAUSE);
  135.         /* Wait for a SIGALRM (or maybe a SIGTINT) */
  136.         while (select_alarmed == 0 && *local_timeout != 0 && process_tick == update_tick) {
  137.             /* If we are interested in terminal input,
  138.                wait by reading the terminal.
  139.                That makes instant wakeup for terminal input at least.  */
  140.             if (orfds & 1) {
  141.                 read_input_waiting ();
  142.                 if (kbd_count)
  143.                     select_alarmed = 1;
  144.             }
  145.             else
  146.                 pause ();
  147.         }
  148.         (*local_timeout) -= SELECT_PAUSE;
  149.         /* Reset the old alarm if there was one */
  150.         alarm (0);
  151.         signal (SIGALRM, old_trap);
  152.         if (old_alarm != 0) {
  153.             /* Reset or forge an interrupt for the original handler. */
  154.             old_alarm -= SELECT_PAUSE;
  155.             if (old_alarm <= 0)
  156.                 kill (getpid (), SIGALRM); /* Fake an alarm with the orig' handler */
  157.             else
  158.                 alarm (old_alarm);
  159.         }
  160.         if (*local_timeout == 0)  /* Stop on timer being cleared */
  161.             break;
  162.     }
  163.     return ravail;
  164. }
  165.  
  166. /* Read keyboard input into the standard buffer,
  167.    waiting for at least one character.  */
  168.  
  169. read_input_waiting ()
  170. {
  171.     extern int kbd_count;
  172.     extern unsigned char kbd_buffer[];
  173.     extern unsigned char *kbd_ptr;
  174.     int val;
  175.     
  176.     val = read (fileno (stdin), kbd_buffer, 1);
  177.     
  178.     if (val > 0)
  179.     {
  180.         kbd_ptr = kbd_buffer;
  181.         kbd_count = val;
  182.     }
  183. }
  184.  
  185. init_sys_modes()
  186. {
  187. }
  188.  
  189. /* Get terminal size from system.
  190.    Store number of lines into *heightp and width into *widthp.
  191.    If zero or a negative number is stored, the value is not valid.  */
  192. get_screen_size(int *widthp,int *heightp)
  193. {
  194.     *widthp = *heightp = 0;
  195. }
  196.  
  197. char *
  198. get_system_name(void)
  199. {
  200.     static char s[256];
  201.     unsigned char **t = (unsigned char **)GetResource('STR ',-16413);
  202.     if (t == 0L) return "";
  203.     HLock((Handle)t);
  204.     pstrcpy(s,*t);
  205.     HUnlock((Handle)t);
  206.     PtoCstr(s);
  207.     return s;
  208. }
  209.  
  210. void
  211. wait_for_termination(int pid)
  212. {
  213.     while (kill(pid, 0) >= 0)
  214.         sleep(1);
  215. }
  216.  
  217. void
  218. sys_suspend(void)
  219. {
  220.     /* We bring the Finder to the front. */
  221.  
  222.     /* A bug in the process manager requires that we loop through all processes
  223.        every time -- we can't simply return when we locate the finder. */
  224.     
  225.     ProcessSerialNumber psn,finder;
  226.     ProcessInfoRec pir;
  227.  
  228.     psn.highLongOfPSN = 0;
  229.     psn.lowLongOfPSN = kNoProcess;
  230.     finder.lowLongOfPSN = kNoProcess;
  231.     pir.processName = 0L;
  232.     pir.processAppSpec = 0L;
  233.  
  234.     while (GetNextProcess(&psn) == noErr)
  235.         if (GetProcessInformation(&psn,&pir) == noErr)
  236.             if (pir.processType == 'FNDR' && pir.processSignature == 'MACS')
  237.                 finder = psn;
  238.  
  239.     if (finder.lowLongOfPSN != kNoProcess) SetFrontProcess(&finder);
  240. }
  241.